/*
Author: Surpass-HC
Source: https://gitee.com/hxchuan000/clpc-1
Mail: surpass-hc@qq.com
*/
#include <clogPrint.h>
int clogPrintCfgLev(clogPrintInfo *logprt, int cfglev)
{
    if (!logprt)
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    if (!(cfglev >= CL_LOG_LEV_FATAL && cfglev < CL_LOG_LEV_MAX))
    {
        printf("[%s,%d]%d\n", __FILE__, __LINE__, cfglev);
    }
    logprt->loglev = LIMIT_VAL(cfglev, CL_LOG_LEV_FATAL, CL_LOG_LEV_MAX - 1);
    return 0;
}
int clogPrintCfgLen(clogPrintInfo *logprt, int cfglen)
{
    if (!logprt)
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    logprt->printMaxLen = LIMIT_VAL(cfglen, clogPrintMinSize, clogPrintMaxSize);
    return 0;
}
int clogPrintCfgWay(clogPrintInfo *logprt, struct clogWayInfo cfgval)
{
    if (!logprt)
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    if (!(cfgval.fun && cfgval.wayName))
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    int sameFlag = 0;
    int findFlag = -1;
    for (int i = 0; i < ARRAY_LEN(logprt->logway); i++)
    {
        if (logprt->logway[i].wayName == NULL)
        {
            if (findFlag < 0)
            {
                findFlag = i;
            }
            continue;
        }
        if (strcmp(logprt->logway[i].wayName, cfgval.wayName))
        {
            continue;
        }
        sameFlag = 1;
        break;
    }
    if (sameFlag)
    {
        printf("[%s,%d]name reged:%s\n", __FILE__, __LINE__, cfgval.wayName);
        return -1;
    }
    if (!(findFlag >= 0 && findFlag < ARRAY_LEN(logprt->logway)))
    {
        printf("[%s,%d]print way full:%d\n", __FILE__, __LINE__, findFlag);
        return -1;
    }
    logprt->logway[findFlag] = cfgval;
    return 1;
}
int clogPrintInit(clogPrintInfo *logprt, int cfglev, int cfglen)
{
    if (!logprt)
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    clogPrintCfgLev(logprt, cfglev);
    clogPrintCfgLen(logprt, cfglen);
    memset(&logprt->logway, 0, sizeof(logprt->logway));
    pthread_mutex_init(&logprt->logLock, NULL);
    return 1;
}
int clogPrintQuit(clogPrintInfo *logprt)
{
    if (!logprt)
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    pthread_mutex_destroy(&logprt->logLock);
    memset(&logprt, 0, sizeof(logprt->logway));
    return 1;
}
int clogPrintFunc(clogPrintInfo *logprt, int lev, const char *fstr, int line, const char *fmt, ...)
{
    if (!logprt)
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    if (!(lev >= 0 && lev <= logprt->loglev))
    {
        return -1;
    }
    if (!(logprt->printMaxLen >= clogPrintMinSize && logprt->printMaxLen <= clogPrintMaxSize))
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    static const char *logstr[] = {
        "fat",
        "err",
        "wrn",
        "inf",
        "dbg",
        "trc"};
    struct timeval tnow;
    struct tm *tmnow;
    gettimeofday(&tnow, NULL);
    tmnow = localtime(&tnow.tv_sec);
    char *tmpstr = (char *)malloc(logprt->printMaxLen);
    const char *tmpFileName;
    (tmpFileName = strrchr(fstr, '/')) ? tmpFileName++ : (tmpFileName = fstr);
    if (!tmpstr)
    {
        printf("[%s,%d]\n", __FILE__, __LINE__);
        return -1;
    }
    int tmplen = snprintf(tmpstr, logprt->printMaxLen, "[%d-%02d-%02d %02d:%02d:%02d.%03d]%s[%s,%d]",
                          tmnow->tm_year + 1900, tmnow->tm_mon + 1, tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec,
                          (int)tnow.tv_usec / 1000 % 1000, logstr[lev], tmpFileName, line);
    va_list args;
    va_start(args, fmt);
    tmplen += vsnprintf(tmpstr + tmplen, logprt->printMaxLen - tmplen, fmt, args);
    va_end(args);
    pthread_mutex_lock(&logprt->logLock);
    if (tmplen < logprt->printMaxLen - 1)
    {
        tmplen++;
    }
    else
    {
        tmplen = logprt->printMaxLen - 1;
    }
    tmpstr[tmplen - 1] = '\n';
    tmpstr[tmplen] = '\0';
    for (int i = 0; i < ARRAY_LEN(logprt->logway); i++)
    {
        // printf("[--do log, %s]%s\n", logprt->logway[i].wayName, tmpstr);
        if (logprt->logway[i].fun)
        {
            logprt->logway[i].fun(logprt->logway[i].wayUserData, tmpstr, tmplen);
        }
    }
    pthread_mutex_unlock(&logprt->logLock);
    free(tmpstr);
    return tmplen;
}
